/*
 * Copyright (c) 2010 Andy Aspell-Clark
 * 
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following
 * conditions:
 * 
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */
package uk.org.aspellclark.agenedb.gedcom;

import java.util.ArrayList;
import java.util.List;

import uk.org.aspellclark.agenedb.db.DatabaseObjectContainer;
import uk.org.aspellclark.agenedb.gedcom.model.Family;
import uk.org.aspellclark.agenedb.gedcom.model.Individual;
import uk.org.aspellclark.agenedb.gedcom.model.Multimedia;
import uk.org.aspellclark.agenedb.gedcom.model.Note;
import uk.org.aspellclark.agenedb.gedcom.model.Repository;
import uk.org.aspellclark.agenedb.gedcom.model.Source;
import uk.org.aspellclark.agenedb.gedcom.model.Submission;
import uk.org.aspellclark.agenedb.gedcom.model.Submitter;

/**
 * Main (root) class for an entire GEDCOM file.
 * 
 * @author Matt
 */
public class Gedcom {

	private static Gedcom instance;

	public static Gedcom getInstance() {
		if (Gedcom.instance == null) {
			Gedcom.instance = new Gedcom();
		}
		return Gedcom.instance;
	}

	//	private Map<String, Family> families = new HashMap<String, Family>();
	//	private Map<String, Individual> individuals = new HashMap<String, Individual>();
	//	private Map<String, Multimedia> multimedia = new HashMap<String, Multimedia>();
	//	private Map<String, Note> notes = new HashMap<String, Note>();
	//	private Map<String, Repository> repositories = new HashMap<String, Repository>();
	//	private Map<String, Source> sources = new HashMap<String, Source>();
	//	private Submission submission;
	//	private Map<String, Submitter> submitters = new HashMap<String, Submitter>();

	private Gedcom() {
	}

	//	public void addFamily(String xref, Family f) {
	//		this.families.put(xref, f);
	//	}
	//
	//	public void addIndividual(String xref, Individual i) {
	//		this.individuals.put(xref, i);
	//	}
	//
	//	public void addMultimedia(String xref, Multimedia m) {
	//		this.multimedia.put(xref, m);
	//	}
	//
	//	public void addNote(String xref, Note n) {
	//		this.notes.put(xref, n);
	//	}
	//
	//	public void addRepository(String xref, Repository r) {
	//		this.repositories.put(xref, r);
	//	}
	//
	//	public void addSource(String xref, Source s) {
	//		this.sources.put(xref, s);
	//	}
	//
	//	public void addSubmitter(String xref, Submitter s) {
	//		this.submitters.put(xref, s);
	//	}

	public void clearOutData() {
		// TODO Auto-generated method stub

	}

	public List<String> getChildren(final Individual individual) {
		if (individual != null) {
			// step 1, find family that this individual is a child of
			List<Family> families = DatabaseObjectContainer.familyCntrlr.getFamilies();
			for (Family f : families) {
				if ((f.wife != null && f.wife.equalsIgnoreCase(individual.xref))
						|| (f.husband != null && f.husband.equalsIgnoreCase(individual.xref))) {
					return f.children;
				}
			}
		}
		return null;
	}

	/**
	 * @return the families
	 */
	public final List<Family> getFamilies() {
		return DatabaseObjectContainer.familyCntrlr.getFamilies();
	}

	public Individual getFather(final Individual individual) {
		Individual indiv = null;
		// step 1, find family that this individual is a child of
		List<Family> families = DatabaseObjectContainer.familyCntrlr.getFamilies();
		for (Family f : families) {
			for (String i : f.children) {
				if (i.equalsIgnoreCase(individual.xref)) {
					indiv = this.getIndividual(f.husband);
					break;
				}
			}
		}
		return indiv;
	}

	public Individual getIndividual(final String xref) {
		return DatabaseObjectContainer.individualCntrlr.getIndividual(xref);
	}

	/**
	 * @return the individuals
	 */
	public final List<Individual> getIndividuals() {
		return DatabaseObjectContainer.individualCntrlr.getIndividuals();
	}

	public List<Individual> getIndividuals(List<String> childrenIds) {
		List<Individual> ppl = new ArrayList<Individual>();
		for (String id : childrenIds) {
			ppl.add(this.getIndividual(id));
		}
		return ppl;
	}

	public Individual getMother(final Individual individual) {
		Individual indiv = null;
		List<Family> families = DatabaseObjectContainer.familyCntrlr.getFamilies();
		for (Family f : families) {
			for (String i : f.children) {
				if (i.equalsIgnoreCase(individual.xref)) {
					indiv = this.getIndividual(f.wife);
					break;
				}
			}
		}
		return indiv;
	}

	/**
	 * @return the multimedia
	 */
	public final List<Multimedia> getMultimedia() {
		return DatabaseObjectContainer.multimediaCntrlr.getMultimediaRecords();
	}

	public Multimedia getMultimedia(String xref) {
		return DatabaseObjectContainer.multimediaCntrlr.getMultimediaRecord(xref);
	}

	public Note getNote(String xref) {
		return DatabaseObjectContainer.noteCntrlr.getNote(xref);
	}

	public final List<Note> getNotes() {
		return DatabaseObjectContainer.noteCntrlr.getNotes();
	}

	/**
	 * @return the repositories
	 */
	public final List<Repository> getRepositories() {
		return DatabaseObjectContainer.repositoryCntrlr.getRepositories();
	}

	/**
	 * @param xref
	 * @return
	 */
	public Repository getRepository(String xref) {
		return DatabaseObjectContainer.repositoryCntrlr.getRepository(xref);
	}

	/**
	 * @param xref
	 * @return
	 */
	public Source getSource(String xref) {
		return DatabaseObjectContainer.sourceCntrlr.getSource(xref);
	}

	/**
	 * @return the sources
	 */
	public final List<Source> getSources() {
		return DatabaseObjectContainer.sourceCntrlr.getSources();
	}

	public Individual getSpouse(final Individual individual) {
		Individual indiv = null;
		List<Family> families = DatabaseObjectContainer.familyCntrlr.getFamilies();
		for (Family f : families) {
			if (f.wife != null && f.wife.equalsIgnoreCase(individual.xref)) {
				indiv = this.getIndividual(f.husband);
				break;
			} else if (f.husband != null && f.husband.equalsIgnoreCase(individual.xref)) {
				indiv = this.getIndividual(f.wife);
				break;
			}
		}
		return indiv;
	}

	/**
	 * @return the submission
	 */
	public final Submission getSubmission() {
		//return DatabaseObjectContainer.submissionCntrlr.getClass();
		return null;
	}

	/**
	 * @param xref
	 * @return
	 */
	public Submitter getSubmitter(String xref) {
		return DatabaseObjectContainer.submitterCntrlr.getSubmitter(xref);
	}

	/**
	 * @return the submitters
	 */
	public final List<Submitter> getSubmitters() {
		return DatabaseObjectContainer.submitterCntrlr.getSubmitters();
	}

}
